package com.nbicc.common.utils;

import java.io.*;

/**
 *
 */
public class RandomAccessFileUtil {

    /**
     * model各个参数详解
     * r 代表以只读方式打开指定文件
     * rw 以读写方式打开指定文件
     * rws 读写方式打开，并对内容或元数据都同步写入底层存储设备
     * rwd 读写方式打开，对文件内容的更新同步更新至底层存储设备
     *
     * **/

    /**
     * 每次读取的缓冲块大小
     */
    public final static int BUFFERSIZE = 4096;

    /**
     *
     * @param path          文件路径
     * @param pos           文件起始指针位置(小于0为不跳过)
     * @param length        读取文件长度(小于等于0为全部读取)
     * @param output        需要输出的流接口
     */
    public static void read(String path,long pos,long length,OutputStream output) throws IOException {
        try (
                RandomAccessFile raf=new RandomAccessFile(path, "r");
        ){
            if(pos>=0){
                raf.seek(pos);//移动文件指针位置
            }
            byte[]  buff=new byte[BUFFERSIZE];
            int hasRead=0;  		//用于保存实际读取的字节数
            long hadRead=0;  		//总共读取了多少字节
            //循环读取
            while((hasRead=raf.read(buff))>0){
                if(length>0 && (length-hadRead)<BUFFERSIZE){
                    hasRead = (int) (length-hadRead);
                    output.write(buff, 0, hasRead);
                    break;
                }
                output.write(buff, 0, hasRead);
                hadRead+=hasRead;
            }
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     *
     * @param path          文件路径
     * @param pos           文件起始指针位置(小于0为追加)
     * @param length        写入文件长度(小于等于0为全部写入)
     * @param input         写入文件流接口
     */
    public static void write(String path,long pos,long length,InputStream input) throws IOException {
        File f = new File(path);
        f.getParentFile().mkdirs();
        try (
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
        ){
            /**以读写的方式建立一个RandomAccessFile对象**/
            if(pos>0){
                raf.seek(pos);
            }
            byte[]  buff=new byte[BUFFERSIZE];
            int hasRead=0;  		//用于保存实际读取的字节数
            long hadRead=0;  		//总共读取了多少字节
            while ((hasRead = input.read(buff)) > 0) {
                if(length>0 && (length-hadRead)<BUFFERSIZE){
                    hasRead = (int) (length-hadRead);
                    raf.write(buff, 0, hasRead);
                    break;
                }
                raf.write(buff, 0, hasRead);
                hadRead+=hasRead;
            }
        } catch (IOException e) {
            throw e;
        }

    }

}
